package com.zn.filter;

import com.alibaba.fastjson.JSONObject;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.http.HttpServletRequestWrapper;
import com.netflix.zuul.http.ServletInputStreamWrapper;
import com.zn.util.AESEncrypt;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.util.StreamUtils;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;

/**
 * @author YinJiaWei
 * @version 2018/10/16 13:05
 */
@Configuration
public class DecryptHandleFilter extends ZuulFilter {
    private static final Logger LOGGER = LoggerFactory.getLogger(DecryptHandleFilter.class);
    @Value("${aesKey}")
    private String aesKey;
    @Value("${unwanted.encrypt.method.uri}")
    private String unwantedEncryptUri;
    @Override
    public String filterType() {
        return "pre";
    }
    @Override
    public int filterOrder() {
        return 0;
    }
    @Override
    public boolean shouldFilter() {
        return true;
    }
    /**
     * 将所有来得请求application/json方式来得进行解密
     * @return
     */
    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String requestURI=request.getRequestURI().toString();
        LOGGER.info(String.format("DecryptHandleFilter..... %s request to %s uri: %s", request.getMethod(), request.getRequestURL().toString(),requestURI));
        try {
            LOGGER.info("request.getContentType:" + request.getContentType());
            List<String> uriList= Arrays.asList(unwantedEncryptUri.split(","));
            if(MediaType.APPLICATION_JSON_VALUE.equals(request.getContentType()) && !uriList.contains(requestURI)){
                InputStream in = request.getInputStream();
                String body = StreamUtils.copyToString(in, Charset.forName("UTF-8"));
                LOGGER.info("body:............." + body);
                JSONObject parseData = JSONObject.parseObject(body);
                if(parseData!=null){
                    String enctyptStr=parseData.get("enctyptData")==null?"":parseData.get("enctyptData").toString();
                    if(StringUtils.isNotBlank(enctyptStr)){
                        String decryptStr=AESEncrypt.aesDecrypt(enctyptStr, aesKey);
                        JSONObject json=JSONObject.parseObject(decryptStr);
                        String newBody = json.toString();
                        LOGGER.info("newBody:"+newBody);
                        final byte[] reqBodyBytes = newBody.getBytes();
                        // 重写上下文的HttpServletRequestWrapper
                        ctx.setRequest(new HttpServletRequestWrapper(request) {
                            @Override
                            public ServletInputStream getInputStream() throws IOException {
                                return new ServletInputStreamWrapper(reqBodyBytes);
                            }
                            @Override
                            public int getContentLength() {
                                return reqBodyBytes.length;
                            }

                            @Override
                            public long getContentLengthLong() {
                                return reqBodyBytes.length;
                            }
                        });
                    }
                }
            }
        }catch (Exception e){
            LOGGER.error("decryptHandle...."+ e);
        }
        return null;
    }

}
